// 获取设备列表、设备控制路由的实现
import express, { Request, Response } from 'express';
import { AppDataSource } from '../../config/database';
import {AccessToken} from "../../entity/Accesstoken";
import { MockThirdPartyMidea } from '../../mock/device-mock/MockThirdPartyMidea';
import { MockThirdPartyXiaomi } from '../../mock/device-mock/MockThirdPartyXiaomi';
import { MideaDevice } from '../../entity/MideaDevice';
import { XiaomiDevice } from '../../entity/XiaomiDevice';
import { User } from '../../entity/User';

const mockDeviceRouter = express.Router();
// mockDeviceRouter.use(express.json());

const mideaService = new MockThirdPartyMidea();
const xiaomiService = new MockThirdPartyXiaomi();

// 初始化时加载分组关系
AppDataSource.initialize().then(async () => {
  const userRepo = AppDataSource.getRepository(User);
  const users = await userRepo.find();
  
  for (const user of users) {
    await xiaomiService.initDeviceGroups(user.userId);
    await mideaService.initDeviceGroups(user.userId);
  }
});

// 美的设备列表
mockDeviceRouter.get('/midea/devices', async (req: Request, res: Response): Promise<void> => {
  const accessToken = req.headers.authorization?.replace('Bearer ', '');
  const clientId = req.headers.clientid as string;
  const reqId = req.query.reqId ? String(req.query.reqId) : "default-req-id";

  if (!accessToken || !clientId) {
    res.status(400).json({
      code: 400,
      message: '缺少必要请求头: Authorization 或 ClientId'
    });
  }

  try {
    const tokenRepo = AppDataSource.getRepository(AccessToken);
    const tokenRecord = await tokenRepo.findOne({
      where: { token: accessToken, appId: clientId }
    });

    if (!tokenRecord || tokenRecord.expiresAt < new Date()) {
      res.status(401).json({
        code: 401,
        message: 'access_token不存在或已过期'
      });
      return;
    }

    const userId = tokenRecord.userId;
    const mideaDeviceRepo = AppDataSource.getRepository(MideaDevice);
    let devices = await mideaDeviceRepo.find({ where: { userId } });

    if (devices.length === 0) {
      const mideaDeviceTypes = ['midea_ac', 'midea_humidifier', 'midea_dehumidifier', 'midea_air_purifier'];
      const newDevices = mideaDeviceTypes.map((type, index) => {
        const device = new MideaDevice();
        device.did = `midea_${type}_${Math.random().toString(36).substring(2, 8)}`;
        device.name = `美的${['空调', '加湿器', '除湿器', '空气净化器'][index]}`;
        device.type = type;
        device.userId = userId;
        device.status = mideaService.generateMideaDeviceData(device.did);
        device.subscribed = false;
        return device;
      });

      await mideaDeviceRepo.save(newDevices);
      devices = newDevices;

      for (const device of devices) {
        await mideaService.pushMideaDeviceStatus(device.did, userId, device.status);
      }
    }

    const response = {
      reqId,
      applianceList: devices.map(device => ({
        virtualId: device.did,
        type: device.type,
        name: device.name,
        online: true
      }))
    };

    res.json({ code: 200, data: response });
  } catch (err: any) {
    res.status(500).json({
      code: 500,
      message: `服务器错误: ${err.message}`
    });
  }
});

// 小米设备列表
mockDeviceRouter.get('/xiaomi/devices', async (req: Request, res: Response): Promise<void> => {
  const accessToken = req.headers['access_token'] as string;
  const appId = req.headers['app_id'] as string;

  if (!accessToken || !appId) {
    res.status(400).json({
      code: 400,
      message: '缺少必要请求头: access_token 或 app_id'
    });
  }

  try {
    const tokenRepo = AppDataSource.getRepository(AccessToken);
    const tokenRecord = await tokenRepo.findOne({
      where: { token: accessToken, appId }
    });

    if (!tokenRecord || tokenRecord.expiresAt < new Date()) {
      res.status(401).json({
        code: 401,
        message: 'access_token无效或已过期'
      });
      return;
    }

    const userId = tokenRecord.userId;
    const xiaomiDeviceRepo = AppDataSource.getRepository(XiaomiDevice);
    let devices = await xiaomiDeviceRepo.find({ where: { userId } });

    if (devices.length === 0) {
      const xiaomiDeviceTypes = ['mi_temp_hum_sensor', 'mi_air_sensor', 'mi_ac', 'mi_humidifier', 'mi_air_purifier'];
      const newDevices = xiaomiDeviceTypes.map((type, index) => {
        const device = new XiaomiDevice();
        device.did = `xiaomi_${type}_${Math.random().toString(36).substring(2, 8)}`;
        device.name = `小米${['温湿度计', '空气质量检测仪', '空调', '加湿器', '空气净化器'][index]}`;
        device.type = type;
        device.userId = userId;
        device.status = xiaomiService.generateXiaomiDeviceData(device.did);
        device.subscribed = false;
        return device;
      });

      await xiaomiDeviceRepo.save(newDevices);
      devices = newDevices;

      for (const device of devices) {
        await xiaomiService.pushXiaomiDeviceStatus(device.did, userId, device.status);
      }
    }

    const response = {
      devices: devices.map(device => ({
        did: device.did,
        name: device.name,
        type: device.type,
        online: true
      }))
    };

    res.json({ code: 200, data: response });
  } catch (err: any) {
    res.status(500).json({
      code: 500,
      message: `服务器错误: ${err.message}`
    });
  }
});


// 美的设备控制路由
mockDeviceRouter.post('/midea/device/control', async (req, res) => {
  const { reqId, applianceId, control } = req.body;
  const accessToken = req.headers.authorization as string;
  const clientId = req.headers.clientid as string;

  try {
    // 验证access_token
    const tokenRepo = AppDataSource.getRepository(AccessToken);
    const tokenRecord = await tokenRepo.findOne({
      where: { token: accessToken, appId: clientId }
    });

    if (!tokenRecord || tokenRecord.expiresAt < new Date()) {
      throw new Error('用户验证失败');
    }

    // 查询设备当前状态
    const mideaDeviceRepo = AppDataSource.getRepository(MideaDevice);
    const device = await mideaDeviceRepo.findOne({
      where: { did: applianceId, userId: tokenRecord.userId }
    });

    if (!device) {
      throw new Error('设备不存在');
    }

    // 检查是否与当前状态相同
    const isSameState = device.status &&
                       device.status[control.operation] === control.value;

    // 使用 MockThirdPartyMidea 执行控制
    const mideaService = new MockThirdPartyMidea();
    const result = await mideaService.controlDevice(accessToken, reqId, applianceId, control);

    // 返回结果
    res.json({
      code: 200,
      ...result,
      isSameState: isSameState ? 1 : 0  // 1表示状态相同，0表示状态已改变
    });  return;
  } catch (err: any) {
    const codeMap: Record<string, number> = {
      '用户验证失败': 1006,
      '设备不存在': 1300,
      '参数非法': 1002
    };

    res.status(400).json({
      code: codeMap[err.message] || 400,
      message: err.message
    });return;
  }
});

// 小米设备控制路由
mockDeviceRouter.post('/xiaomi/device/control', async (req, res) => {
  const { did, control } = req.body;
  const accessToken = req.headers.access_token as string;
  const appId = req.headers.app_id as string;

  try {
    // 验证access_token
    const tokenRepo = AppDataSource.getRepository(AccessToken);
    const tokenRecord = await tokenRepo.findOne({
      where: { token: accessToken, appId }
    });

    if (!tokenRecord || tokenRecord.expiresAt < new Date()) {
      throw new Error('授权过期');
    }

    // 查询设备当前状态
    const xiaomiDeviceRepo = AppDataSource.getRepository(XiaomiDevice);
    const device = await xiaomiDeviceRepo.findOne({
      where: { did, userId: tokenRecord.userId }
    });

    if (!device) {
      throw new Error('设备不存在');
    }

    // 检查是否与当前状态相同
    const isSameState = device.status &&
                       device.status[control.operation] === control.value;

    // 使用 MockThirdPartyXiaomi 执行控制
    const xiaomiService = new MockThirdPartyXiaomi();
    const result = await xiaomiService.controlDevice(accessToken, did, control);

    // 返回结果
    res.json({
      ...result,
      isSameState: isSameState ? 1 : 0  // 1表示状态相同，0表示状态已改变
    }); return;
  } catch (err: any) {
    const codeMap: Record<string, number> = {
      '授权过期': 903,
      '设备不存在': 1,
      '属性不存在': 3,
      '属性值错误': 43
    };

    res.status(400).json({
      code: codeMap[err.message] || 400,
      message: err.message
    }); return;
  }
});


export default mockDeviceRouter;
